<?php
class Project extends ObjectModel {

    public $id;
    public $id_owner;
    public $id_cms;
    public $id_product;
    public $name;
    public $description;
    public $active;
    public $is_public;
	public $date_add;
    public $date_upd;
    
    // Additional attrbutes
    protected $styles = array();
    protected $zipPath = '';
    protected $downlaodPath = '';
    
    public $product;
    
    public static $definition = array(
        'table' => 'pt_project',
        'primary' => 'id_project',
        'multilang' => false,
        'fields' => array(
            'id_owner' => array(
                'type' => ObjectModel::TYPE_INT,
                'required' => true, 
                'validate' => 'isUnsignedId'
            ),
            'id_cms' => array(
                'type' => ObjectModel::TYPE_INT,
                'required' => true, 
                'validate' => 'isUnsignedId'
            ),
            'id_product' => array(
                'type' => ObjectModel::TYPE_INT,
                'validate' => 'isUnsignedId'
            ),
            'name' => array(
                'type' => ObjectModel::TYPE_STRING,
                'required' => true,
                'validate' => 'isTplName', 
                'size' => 64
            ),
            'description' => array(
                'type' => ObjectModel::TYPE_STRING
            ),
            'active' => array(
                'type' => ObjectModel::TYPE_BOOL,
                'required' => true
            ),
            'is_public' => array(
                'type' => ObjectModel::TYPE_BOOL,
                'required' => true
            ),
            'date_add' =>  array(
                'type' => self::TYPE_DATE, 
                'validate' => 'isDateFormat'
            ),
			'date_upd' => array(
                'type' => self::TYPE_DATE,
                'validate' => 'isDateFormat'
            )

        )
    );
    
    public static function findByIdOwner ($id_owner)
    {
        $sql = 'select * from `' . _DB_PREFIX_ . 'pt_project` where `active` = 1 AND `id_owner` = '. (int)$id_owner;
        if ($rows = Db :: getInstance(_PS_USE_SQL_SLAVE_)->ExecuteS($sql)) 
        {
            return ObjectModel :: hydrateCollection(__CLASS__, $rows);
        }
        return array();
    }
    
    public function getCMSName ()
    {
        $cms = new PrestathemeCms ($this->id_cms, Context::getContext()->language->id);
        if ($cms)
            return $cms->getCMSName();
        else
            return NULL;
    }
    
    public function getProductName ()
    {
        if (!$this->product)
            $this->product = new Product ($this->id_product);
        if ($this->product->id)
            return $this->product->name[Context::getContext()->language->id];
        else
            return NULL;
    }
    
    public function getOwnerName ($full = false)
    {
        $user = new Customer ($this->id_owner);
        if ($user)
            return $user->firstname .' '. $user->lastname . ($full ? (' &lt;'. $user->email .'&gt;') : '');
        else
            return NULL;
    }
    
    public function generateCSS ()
    {
		// default style
		$sql = new DbQuery();
		$sql->from('pt_default_style', 'a');
		$sql->where('a.id_cms = '.(int)$this->id_cms.' AND a.active = 1');
		$result = self::$db->executeS($sql);
		if ($result)
		{
			foreach ($result as $row)
			{
				$row['selector'] = trim($row['selector']);
				$this->styles[$row['selector']] = array();
				$this->styles[$row['selector']] = self::cssToArray($row['style'], $this->styles[$row['selector']]);
			}
		}
		
		// Update with custom style
		$sql = new DbQuery();
		$sql->from('pt_custom_style', 'a');
		$sql->where('a.id_project = '.(int)$this->id);
		$result = self::$db->executeS($sql);
		if ($result)
		{
			foreach ($result as $row)
			{
				$row['selector'] = trim($row['selector']);
				if (empty($this->styles[$row['selector']]))
					$this->styles[$row['selector']] = array();
				$this->styles[$row['selector']] = self::cssToArray($row['style'], $this->styles[$row['selector']]);
			}
		}
        
        // Get style from the selected design
		$sql = new DbQuery();
        $sql->select('style');
		$sql->from('pt_configured_design', 'a');
        $sql->leftJoin('pt_preconfigured_design', 'pd', 'a.namespace = pd.namespace AND a.key_name = pd.key_name');
		$sql->where('a.id_project = '.(int)$this->id.' AND pd.active = 1');
		$result = self::$db->executeS($sql);
        if ($result)
		{
			foreach ($result as $row)
			{
                if ($row['style'])
                {
                    $styles = explode('}', $row['style']);
                    foreach ($styles AS $style)
                    {
                        $style = explode('{', $style);
            			
                        if (count($style) != 2) continue;
                        
                        $style[0] = trim($style[0]);
                        $style[1] = trim($style[1]);
        				if (empty($this->styles[$style[0]]))
        					$this->styles[$style[0]] = array();
        				$this->styles[$style[0]] = self::cssToArray($style[1], $this->styles[$style[0]]);
                    }
                }
			}
		}
        
        return $this->styles;
    }
    
    public function concatToGridPrestashopFile ($gridPrestashopFile, $styles)
    {
        $contents = '';
        if (is_file($gridPrestashopFile))
            $contents = file_get_contents($gridPrestashopFile);
        
        $contents .= "\r\n\r\n";
        $contents .= "/*================================================*/\r\n";
        $contents .= "/*               Add by presta-theme              */\r\n";
        $contents .= "/*================================================*/\r\n\r\n";
        
        if (is_array($styles))
            foreach ($styles AS $selector => $style)
            {
                $contents .= $selector ."\r\n{\r\n";
                foreach ($style AS $attr => $value)
                {
                    $contents .= "\t". $attr .":". $value .";\r\n";
                }
                $contents .= "}\r\n\r\n";
            }
        return $contents;
    }
    
    public function makePackage ($defaultThemeDir, $customFiles = array(), $filesToRemove = array())
    {
        if (is_dir($defaultThemeDir))
        {
            $fileTime = date("D, d M Y H:i:s T");
            
            $zip = new Zip();
            $this->zipPath = _PS_MODULE_DIR_ .'prestatheme/API/data/generated/'. $this->name .'_'. strtotime($this->date_add) .'.zip';
            $zip->setZipFile($this->zipPath);
            
            // Add comment
            $comments = file_get_contents(_PS_MODULE_DIR_ .'prestatheme/API/data/docs/comment.txt');
            $comments = str_replace('{toto.zip}', $this->name ." [Created on " . date('l jS \of F Y h:i:s A') ."]", $comments);
            $zip->setComment($comments);
            
            // Add custom files
            if (is_array($customFiles))
                foreach ($customFiles AS $zipPath => $content)
                {
                    $zip->openStream($zipPath);
                    $zip->addStreamData($content);
                    $zip->closeStream();
                }
            
            // Add all the default theme
            $addedFiles = array();
            $zip->addDirectoryContent($defaultThemeDir, "themes/".$this->name, TRUE, TRUE, $addedFiles, $filesToRemove);
            $zip->finalize();
            
            // Save a copy to the prestashop download directory
            $this->downlaodPath = sha1(microtime());
            $zip->setZipFile(_PS_DOWNLOAD_DIR_ . $this->downlaodPath);
            
            return $zip->getZipFile();
        }
        return false;
    }
    
    public function makeProduct ($zipFileHandle)
    {
        $product = new Product((int)$this->id_product);
        $configs = Configuration::getMultiple(
            array(
                PrestaTheme::$CONFIGURATIONVAR .'WHOLESALE_PRICE',
                PrestaTheme::$CONFIGURATIONVAR .'PRICE',
                PrestaTheme::$CONFIGURATIONVAR .'ID_TAX_RULES_GROUP',
                
                PrestaTheme::$CONFIGURATIONVAR .'EXPIRED_DATE',
                PrestaTheme::$CONFIGURATIONVAR .'NBR_DAYS',
                PrestaTheme::$CONFIGURATIONVAR .'NBR_DOWNLOAD_ALLOWED',
                PrestaTheme::$CONFIGURATIONVAR .'IS_SHAREABLE',
            )
        );
        $ok = true;
        
        $product->is_virtual = true;
        $product->id_category_default = 2;
        $product->id_supplier = 0;
        $product->id_manufacturer = 0;
        $product->id_shop_default = Context::getContext()->shop->id;
        
        // Define the product
        $product->name = array();
        $product->description_short = array();
        $product->description = array();
        
        $product->available_now = array();
        $product->available_later = array();
        
        $product->link_rewrite = array();
        $product->meta_title = array();
        $product->meta_description = array();
        $product->meta_keywords = array();
        $languages = Language::getLanguages(false);
		foreach ($languages as $language)
        {
            $product->name[(int)$language['id_lang']] = $this->name;
            $product->description_short[(int)$language['id_lang']] = $this->description;
            $product->description[(int)$language['id_lang']] = $this->description;
            
            $product->available_now[(int)$language['id_lang']] = '';
            $product->available_later[(int)$language['id_lang']] = '';
            
            $product->link_rewrite[(int)$language['id_lang']] = str_replace(' ', '-', strtolower($this->name));
            $product->meta_title[(int)$language['id_lang']] = '';
            $product->meta_description[(int)$language['id_lang']] = '';
            $product->meta_keywords[(int)$language['id_lang']] = preg_replace('/ *,? +,* /', ',', strtolower('prestatheme,prestashop,1.5.x,theme,template,generator,editor,'. $this->name .','. $this->getOwnerName()));
        }
        
        // Set by configuration informations
        $product->wholesale_price    = str_replace(',', '.', $configs[PrestaTheme::$CONFIGURATIONVAR .'WHOLESALE_PRICE']);
        $product->price              = str_replace(',', '.', $configs[PrestaTheme::$CONFIGURATIONVAR .'PRICE']);
        $product->id_tax_rules_group = (int)$configs[PrestaTheme::$CONFIGURATIONVAR .'ID_TAX_RULES_GROUP'];
        
        // Default value
        $product->reference = '';
        $product->ean13 = '';
        $product->upc = '';
        $product->visibility = 'both';
        $product->active = true;
        $product->available_for_order = true;
        $product->show_price = true;
        $product->on_sale = false;
        $product->online_only = false;
        $product->unity = '';
        $product->width = 0.000000;
        $product->height = 0.000000;
        $product->depth = 0.000000;
        $product->weight = 0.000000;
        $product->additional_shipping_cost = 0.00;
        $product->minimal_quantity = 1;
        $product->available_date = '0000-00-00';
        
        $update = (int)$product->id;
        if ($ok AND $product->save())
        {
            // Default category
            $product->updateCategories(array(2));
            
            // Hook action
            if ($update)
                Hook::exec('actionProductAdd', array('product' => $product));
            else
                Hook::exec('actionProductUpdate', array('product' => $product));
            
            // Search indexation
            if (in_array($product->visibility, array('both', 'search')) && Configuration::get('PS_SEARCH_INDEXATION'))
                Search::indexation(false, $product->id);
                
            // Update tag            
            /* Reset all tags for THIS product */
            Tag::deleteTagsForProduct((int)$product->id);
            /* Assign tags to this product */
            $tag_success = true;
            foreach ($languages as $language)
            {
                $value = preg_replace('/ *,? +,* /', ',', strtolower('generated-theme,'. $this->name .','. $this->getOwnerName()));
                $tag_success &= Tag::addTags($language['id_lang'], (int)$product->id, $value);
            }
            
            // Associated the product
			$id_product_download = (int)ProductDownload::getIdFromIdProduct((int)$product->id);
            if (!$id_product_download)
                $id_product_download = 0;
            
            $download = new ProductDownload($id_product_download);
			
			// We delete the previous file if necessary
			$download->deleteFile();
			
			$download->id_product = (int)$product->id;
			$download->display_filename = $this->name .'_'. strtotime($this->date_add);
			$download->filename = $this->downlaodPath;
			$download->date_add = date('Y-m-d H:i:s');
			$download->date_expiration = $configs[PrestaTheme::$CONFIGURATIONVAR .'EXPIRED_DATE'] .' 23:59:59';
			$download->nb_days_accessible = (int)$configs[PrestaTheme::$CONFIGURATIONVAR .'NBR_DAYS'];
			$download->nb_downloadable = (int)$configs[PrestaTheme::$CONFIGURATIONVAR .'NBR_DOWNLOAD_ALLOWED'];
			$download->active = 1;
			$download->is_shareable = (int)$configs[PrestaTheme::$CONFIGURATIONVAR .'IS_SHAREABLE'];
            
            if ($download->save())
            {
                $this->id_product = $product->id;
                $ok = $this->save();
            }
        }
        return $ok;
    }
	
	public static function cssToArray($style, $result = array())
	{
		if (!is_array($result))
			$result = array();
		
		$style = trim($style, '{');
		$style = trim($style, '}');
		$style = explode(';', $style);
		foreach ($style AS $stylecss)
		{
			if (empty($stylecss)) continue;
			
			$stylecss = explode(':', $stylecss);
			
            if (count($stylecss) != 2) continue;
            
			$result[trim($stylecss[0])] = $stylecss[1];
		}
		
		return $result;
	}
}